package dcutils.cards.mtg;

/**
 * Represents a single creature card in Magic the Gathering.<br/>
 * @author dca
 */
public class CreatureCard extends Card {
	// CUSTOM EXCEPTIONS

	public static class PowerException extends Exception {
		/** Unique ID for serialization */
		private static final long serialVersionUID = 7547354291706343464L;

		public PowerException(String msg) {
			super(msg);
		} // END constructor
	} // END exception class PowerException
	public static class ToughnessException extends Exception {
		/** Unique ID for serialization */
		private static final long serialVersionUID = -7346671891568663526L;

		public ToughnessException(String msg) {
			super(msg);
		} // END constructor
	} // END exception class ToughnessException

	// FIELDS

	private String power;
	private String toughness;

	public CreatureCard(
		String cardName,
		Rarity rarity,
		Expansion expansion,
		String creatureType,
		String power,
		String toughness
	) throws PowerException, ToughnessException {
		super(cardName, rarity, expansion, String.format("Creature - %s", creatureType));
		setPower(power);
		setToughness(toughness);
	} // END constructor

	public CreatureCard(
		String cardName,
		ManaCost manaCost,
		Rarity rarity,
		Expansion expansion,
		String creatureType,
		String power,
		String toughness
	) throws PowerException, ToughnessException {
		super(cardName, manaCost, rarity, expansion, String.format("Creature - %s", creatureType));
		setPower(power);
		setToughness(toughness);
	} // END constructor

	public CreatureCard(
		String cardName,
		Rarity rarity,
		Expansion expansion,
		CreatureType creatureType,
		String power,
		String toughness
	) throws PowerException, ToughnessException {
		super(cardName, rarity, expansion, String.format("Creature - %s", creatureType));
		setPower(power);
		setToughness(toughness);
	} // END constructor

	public CreatureCard(
		String cardName,
		ManaCost manaCost,
		Rarity rarity,
		Expansion expansion,
		CreatureType creatureType,
		String power,
		String toughness
	) throws PowerException, ToughnessException {
		super(cardName, manaCost, rarity, expansion, String.format("Creature - %s", creatureType));
		setPower(power);
		setToughness(toughness);
	} // END constructor

	public String getPower() {
		return this.power;
	} // END getPower

	public int getPowerAsInt() {
		return Integer.parseInt(this.power);
	} // END getPowerAsInt

	public void setPower(String power) throws PowerException {
		if(null != power && !"*".equals(power) && !power.matches("\\d+")) {
			throw new PowerException(String.format("power format is incorrect: %s", power));
		} // END if

		this.power = power;
	} // END setPower

	public String getToughness() {
		return this.toughness;
	} // END getToughness

	public int getToughnessAsInt() {
		return Integer.parseInt(this.toughness);
	} // END getToughnessAsInt

	public void setToughness(String toughness) throws ToughnessException {
		if(null != toughness && !"*".equals(toughness) && !toughness.matches("\\d+")) {
			throw new ToughnessException(String.format("toughness format is incorrect: %s", power));
		} // END if

		this.toughness = toughness;
	} // END setToughness

	@Override
	public String toString() {
		StringBuffer buffer = new StringBuffer(1024);
		buffer.append(this.getClass().getSimpleName()); buffer.append(" [");

		buffer.append(super.toString().replaceFirst("^.*\\[", "").replaceFirst("\\].*$", ""));
		buffer.append(", ");
		buffer.append(String.format("%s = %s", "power", getPower()));
		buffer.append(", ");
		buffer.append(String.format("%s = %s", "toughness", getToughness()));

		buffer.append("]");
		return buffer.toString();
	} // END toString

	@Override
	public boolean equals(Object obj) {
		if(null == obj) {
			return false;
		} else if(obj instanceof CreatureCard) {
			CreatureCard card = (CreatureCard)obj;
			return super.equals(card) &&
				   this.getPower().equals(card.getPower()) &&
				   this.getToughness().equals(card.getToughness());
		} else {
			return false;
		} // END if/else
	} // END equals

	@Override
	public int hashCode() {
		int hashCode = 101;
		hashCode = (11 * hashCode) + super.hashCode();
		hashCode = (11 * hashCode) + (null == getPower()     ? -1 : getPower().hashCode());
		hashCode = (11 * hashCode) + (null == getToughness() ? -1 : getToughness().hashCode());
		return hashCode;
	} // END hashCode

	@Override
	public String prettyPrint() {
		StringBuffer buffer = new StringBuffer(1024);
		buffer.append(this.getClass().getSimpleName()); buffer.append(String.format(" [%n"));

		buffer.append(String.format("\t%s = %s", "cardName", getCardName()));
		buffer.append(String.format(",%n"));
		buffer.append(String.format("\t%s = %s", "manaCost", getManaCost().prettyPrint().replace("\t", "\t\t")));
		buffer.append(String.format(",%n"));
		buffer.append(String.format("\t%s = %s", "rarity", getRarity()));
		buffer.append(String.format(",%n"));
		buffer.append(String.format("\t%s = %s", "expansion", getExpansion()));
		buffer.append(String.format(",%n"));
		buffer.append(String.format("\t%s = %s", "typeLine", getTypeLine()));
		buffer.append(String.format(",%n"));
		buffer.append(String.format("\t%s = %s", "cardText", getCardText()));
		if(hasFlavorText()) buffer.append(String.format(",%n"));
		if(hasFlavorText()) buffer.append(String.format("\t%s = %s", "flavorText", getFlavorText()));
		buffer.append(String.format(",%n"));
		buffer.append(String.format("\t%s = %s", "power", getPower()));
		buffer.append(String.format(",%n"));
		buffer.append(String.format("\t%s = %s", "toughness", getToughness()));

		buffer.append(String.format("%n]"));
		return buffer.toString();
	} // END prettyPrint
} // END class CreatureCard
